#include "LobbyEvent.h"

#include "LobbyContainer.h"
#include "LobbyClient.h"
#include "LobbyFriend.h"
#include "LobbyGame.h"
#include "LobbyGroup.h"
#include "LobbyServer.h"
#include "WONLobbyPrv.h"

#include "WONMisc/GetHTTPDocumentOp.h"

using namespace WONAPI;

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static void LobbyListener(ComponentEvent *theEvent)
{
	if(gLobbyData.get()!=NULL)
		gLobbyData->mLogicMgr.HandleComponentEvent(theEvent);
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static void LobbyTimer(void *)
{
	if(gLobbyData.get()==NULL)
		return;

	gLobbyData->mLogicMgr.DispatchTimerEvent();

}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void LobbyEvent::Init()
{
	if(gLobbyData.get()==NULL)
		return;

	// Listen to events from the lobby
	ListenToComponent(gLobbyData->mLobbyContainer);

	// Listen for timer
	gLobbyData->mTimerEvent = new UserEvent(LobbyTimer);
	WindowManager::GetDefaultWindowManager()->AddTimerEvent(gLobbyData->mTimerEvent);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void LobbyEvent::Destroy()
{
	if(gLobbyData.get()==NULL)
		return;

	gLobbyData->mLobbyContainer->SetListener(NULL);
	WindowManager *aWindowMgr = WindowManager::GetDefaultWindowManager();
	if(aWindowMgr!=NULL)
	{
		aWindowMgr->RemoveTimerEvent(gLobbyData->mTimerEvent);
		aWindowMgr->ClearSubscriptions(); // FIXME, just clear lobby subscriptions
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void LobbyEvent::ListenToComponent(Component *theComponent)
{
	if(theComponent!=NULL)
		theComponent->SetListener(new ComponentListenerFunc(LobbyListener));
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void LobbyEvent::BroadcastEvent(LobbyEvent *theEvent, bool sendNow)
{
	if(gLobbyData.get()!=NULL)
		gLobbyData->mLobbyContainer->BroadcastEvent(theEvent,sendNow);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void LobbyEvent::BroadcastEvent(int theEventType, bool sendNow)
{
	if(gLobbyData.get()!=NULL)
	{
		LobbyEventPtr anEvent = new LobbyEvent(theEventType);
		gLobbyData->mLobbyContainer->BroadcastEvent(anEvent,sendNow);
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void LobbyEvent::DeliverEventTo(LobbyEvent *theEvent, Component *theComponent)
{

	LobbyEventPtr anEvent = theEvent; // make sure event is reference counted
	if(gLobbyData.get()!=NULL && theComponent!=NULL)
	{
		if(theEvent->mComponent==NULL)
			theEvent->SetComponent(gLobbyData->mLobbyContainer);

		theEvent->mBroadcast = true; // this way the event won't propagate up if not handled
		theComponent->HandleComponentEvent(theEvent);
	}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void LobbyEvent::DeliverLogicEvent(LobbyEvent *theEvent)
{
	LobbyEventPtr anEvent = theEvent; // make sure event is reference counted
	if(gLobbyData.get()!=NULL)
	{
		if(theEvent->mComponent==NULL)
			theEvent->SetComponent(gLobbyData->mLobbyContainer);

		LobbyListener(theEvent);
	}

}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void LobbyEvent::DeliverLogicEvent(int theEventType)
{
	if(gLobbyData.get()!=NULL)
	{
		LobbyEventPtr anEvent = new LobbyEvent(theEventType);
		anEvent->SetComponent(gLobbyData->mLobbyContainer);
		LobbyListener(anEvent);
	}
}



///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
LobbyChangeEvent::LobbyChangeEvent(int theEventType, LobbyChangeType theChangeType) : 
	LobbyEvent(theEventType), mChangeType(theChangeType) 
{ 
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool LobbyChangeEvent::IsAdd()
{
	return mChangeType==LobbyChangeType_Add;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool LobbyChangeEvent::IsDelete()
{
	return mChangeType==LobbyChangeType_Delete;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool LobbyChangeEvent::IsModify()
{
	return mChangeType==LobbyChangeType_Modify;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AcceptClientEvent::AcceptClientEvent(LobbyClient *theClient, bool accepted) : 
	LobbyEvent(LobbyEvent_AcceptClient), mClient(theClient) 
{
	mAccepted = accepted;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AcceptClientEvent::~AcceptClientEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AlertEvent::AlertEvent(int theRoomSpec, AlertAction theAction, unsigned long theTimeLeft, const GUIString& theComment) :
	LobbyEvent(LobbyEvent_Alert)
{
	mRoomSpec = theRoomSpec;
	mAction = theAction;
	mTimeLeft = theTimeLeft;
	mComment = theComment;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AlertEvent::~AlertEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AnnounceClientLocationEvent::AnnounceClientLocationEvent(LobbyClient *theClient, const GUIString &theChatName, 
														 const GUIString &theGameName, int theSpecFlags) :
	LobbyEvent(LobbyEvent_AnnounceClientLocation), mClient(theClient), mGameName(theGameName),
		mChatName(theChatName), mRoomSpec(theSpecFlags)
{
	mHandled = false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AnnounceClientLocationEvent::~AnnounceClientLocationEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AnnounceFriendEvent::AnnounceFriendEvent(LobbyFriend *theFriend, int theSpecFlags, LobbyChangeType theChangeType) :
	LobbyChangeEvent(LobbyEvent_AnnounceFriend,theChangeType), mFriend(theFriend), mRoomSpec(theSpecFlags)
{
	mHandled = false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AnnounceFriendEvent::~AnnounceFriendEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ChangeDirectConnectEvent::ChangeDirectConnectEvent(LobbyChangeType theType, LobbyGame *theGame) :
	  LobbyChangeEvent(LobbyEvent_ChangeDirectConnect, theType), mGame(theGame)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ChangeDirectConnectEvent::~ChangeDirectConnectEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ClientActionEvent::ClientActionEvent(LobbyClientAction theAction, const LobbyRoomSpec &theSpec, LobbyClient *theClient) :
	LobbyEvent(LobbyEvent_ClientAction), mClient(theClient), mRoomSpec(theSpec)
{
	mAction = theAction;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ClientActionEvent::~ClientActionEvent()
{
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ClientChangedEvent::ClientChangedEvent(LobbyClient *theClient, const LobbyRoomSpec &theSpec, LobbyChangeType theChangeType) : 
	LobbyChangeEvent(LobbyEvent_ClientChanged, theChangeType), mClient(theClient), mRoomSpec(theSpec)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ClientChangedEvent::~ClientChangedEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ClientModeratedEvent::ClientModeratedEvent(LobbyClient *theClient, int theRoomSpec, const GUIString& theRoomName, ModerationAction theAction, unsigned long theDuration, bool isMe, const GUIString& theComment) :
	LobbyEvent(LobbyEvent_ClientModerated), mClient(theClient), mRoomName(theRoomName)
{
	mRoomSpec = theRoomSpec;
	mDuration = theDuration;
	mAction = theAction;
	mIsMe = isMe;
	mComment = theComment;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ClientModeratedEvent::~ClientModeratedEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
FriendActionEvent::FriendActionEvent(LobbyFriendAction theAction, LobbyFriend *theFriend, int theRoomSpecFlags) :
	LobbyEvent(LobbyEvent_FriendAction), mFriend(theFriend)
{
	mAction = theAction;
	mRoomSpecFlags = theRoomSpecFlags;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
FriendActionEvent::~FriendActionEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
FriendChangedEvent::FriendChangedEvent(LobbyFriend *theFriend, LobbyChangeType theChangeType) :
	LobbyChangeEvent(LobbyEvent_FriendChanged, theChangeType), mFriend(theFriend)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
FriendChangedEvent::~FriendChangedEvent()
{
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GameActionEvent::GameActionEvent(LobbyGameAction theAction, LobbyGame *theGame) :
	LobbyEvent(LobbyEvent_GameAction), mGame(theGame)
{
	mAction = theAction;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GameActionEvent::~GameActionEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GameChangedEvent::GameChangedEvent(LobbyGame *theGame, LobbyChangeType theType) :
	LobbyChangeEvent(LobbyEvent_GameChanged, theType), mGame(theGame)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GameChangedEvent::~GameChangedEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GotHTTPDocumentEvent::GotHTTPDocumentEvent(GetHTTPDocumentOp *theOp) :
	LobbyEvent(LobbyEvent_GotHTTPDocument), mOp(theOp) 
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GotHTTPDocumentEvent::~GotHTTPDocumentEvent()
{
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GroupChangedEvent::GroupChangedEvent(LobbyGroup *theGroup, LobbyServer *theServer, LobbyChangeType theType) :
	LobbyChangeEvent(LobbyEvent_GroupChanged, theType), mGroup(theGroup), mServer(theServer)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GroupChangedEvent::~GroupChangedEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
GroupInvitationEvent::GroupInvitationEvent(int theRoomSpecFlags, const GUIString &theGroupName, 
										   unsigned short theGroupId, LobbyClient *theClient, bool invited, 
										   const GUIString &theComment, bool fromMe) :
	LobbyEvent(LobbyEvent_GroupInvitation), mRoomSpec(theRoomSpecFlags), mGroupName(theGroupName),
		mClient(theClient), mComment(theComment)
{
	mGroupId = theGroupId;
	mInvited = invited;
	mFromMe = fromMe;
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
GroupInvitationEvent::~GroupInvitationEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GroupJoinAttemptEvent::GroupJoinAttemptEvent(int theRoomSpecFlags, LobbyClient *theClient, const GUIString &theComment) :
	LobbyEvent(LobbyEvent_GroupJoinAttempt), mRoomSpec(theRoomSpecFlags), mClient(theClient), mComment(theComment)
{
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
GroupJoinAttemptEvent::~GroupJoinAttemptEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
JoinFriendsRoomEvent::JoinFriendsRoomEvent(LobbyFriend *theFriend) : 
	LobbyEvent(LobbyEvent_JoinFriendsRoom), mFriend(theFriend) 
{
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
JoinFriendsRoomEvent::~JoinFriendsRoomEvent()
{
}


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
JoinGameEvent::JoinGameEvent(LobbyGame *theGame) :
	LobbyEvent(LobbyEvent_JoinGame), mGame(theGame)
{
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
JoinGameEvent::~JoinGameEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
JoinedRoomEvent::JoinedRoomEvent(const GUIString &theServerName, const GUIString &theRoomName, 
								 const LobbyRoomSpec &theSpec, unsigned short myClientId, LobbyClientList *theClientList)  :
	LobbyEvent(LobbyEvent_JoinedRoom), mServerName(theServerName), mRoomName(theRoomName), 
	mRoomSpec(theSpec), mMyClientId(myClientId), mClientList(theClientList)
{
	
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
JoinedRoomEvent::~JoinedRoomEvent()
{
}


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
PingGameEvent::PingGameEvent(LobbyGame *theGame, bool getDetails) : 
	LobbyEvent(LobbyEvent_PingGame), mGame(theGame)
{
	mGetDetails = getDetails;
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
PingGameEvent::~PingGameEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
PlayerChangedEvent::PlayerChangedEvent(LobbyClient *theClient, LobbyChangeType theChangeType) : 
	LobbyChangeEvent(LobbyEvent_PlayerChanged, theChangeType), mClient(theClient)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
PlayerChangedEvent::~PlayerChangedEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
PlayerTeamChangedEvent ::PlayerTeamChangedEvent(LobbyClient *theClient, LobbyChangeType theChangeType) : 
	LobbyChangeEvent(LobbyEvent_PlayerTeamChanged, theChangeType), mClient(theClient)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
PlayerTeamChangedEvent::~PlayerTeamChangedEvent()
{
}


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
RecvChatEvent::RecvChatEvent(const LobbyRoomSpec &theSpec, int theChatFlags, LobbyClient *theSender, const GUIString &theText, LobbyClient *theDestClient) :
	LobbyEvent(LobbyEvent_RecvChat), mSender(theSender), mDestClient(theDestClient), mText(theText),
		mRoomSpec(theSpec)
{
	mChatFlags = theChatFlags;
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
RecvChatEvent::~RecvChatEvent()
{
}
	
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
bool RecvChatEvent::IsWhisper()
{
	return mChatFlags&LobbyChatFlag_IsWhisper?true:false;
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
bool RecvChatEvent::IsEmote()
{
	return mChatFlags&LobbyChatFlag_IsEmote?true:false;
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
bool RecvChatEvent::IsWarning()
{
	return mChatFlags&LobbyChatFlag_IsWarning?true:false;
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
bool RecvChatEvent::IsTeam()
{
	return mChatFlags&LobbyChatFlag_TeamChat?true:false;
}

///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
ServerChangedEvent::ServerChangedEvent(LobbyServer *theServer, LobbyChangeType theType) :
	LobbyChangeEvent(LobbyEvent_ServerChanged, theType), mServer(theServer)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ServerChangedEvent::~ServerChangedEvent()
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SyncGameListEvent::SyncGameListEvent(LobbyGameList *theGameList) : 
	LobbyEvent(LobbyEvent_SyncGameList), mGameList(theGameList)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SyncGameListEvent::~SyncGameListEvent()
{
}

